package com.libcommon

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.widget.ImageView
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import com.blankj.utilcode.util.ColorUtils
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.SizeUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.libcommon.ext.workIO
import com.libcommon.ext.workUI
import jp.wasabeef.glide.transformations.BlurTransformation
import jp.wasabeef.glide.transformations.CropCircleWithBorderTransformation
import jp.wasabeef.glide.transformations.GrayscaleTransformation
import jp.wasabeef.glide.transformations.RoundedCornersTransformation
import java.io.File

/**
 * Glide工具类
 */
@SuppressLint("CheckResult")
object GlideManager {

    /*** 占位图  */
    private var placeholderImage = R.drawable.shape_translucent

    /**
     * 加载图片(默认)
     *
     * @param context   上下文
     * @param url       链接 或 本地文件路径 或 asset路径
     * @param imageView ImageView
     */
    fun loadImage(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        @DrawableRes placeholderId: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions()
            .dontAnimate()
            .placeholder(placeholderId)   //占位图
            .error(placeholderId)         //错误图
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 加载本地路径文件
     * @param path 文件路径
     */
    fun loadImageFileByPath(context: Context?, path: String?, imageView: ImageView?) {
        if (context == null || !FileUtils.isFileExists(path) || imageView == null) return

        val options = RequestOptions()
            .placeholder(placeholderImage)   //占位图
            .error(placeholderImage)         //错误图
        Glide.with(context).load(path).apply(options).into(imageView)
    }

    /**
     * 加载本地路径文件
     * @param file 文件
     */
    fun loadImageFile(context: Context?, file: File?, imageView: ImageView?) {
        if (context == null || !FileUtils.isFileExists(file) || imageView == null) return

        val options = RequestOptions()
            .placeholder(placeholderImage)   //占位图
            .error(placeholderImage)               //错误图
        Glide.with(context).load(file).apply(options).into(imageView)
    }

    /**
     * 加载本地路径文件  本地大图用这个 一般用于背景图
     * @param drawableId 资源id
     */
    fun loadImageDrawableId(context: Context?, @DrawableRes drawableId: Int, imageView: ImageView?) {
        if (context == null || drawableId == 0 || imageView == null) return

        val options = RequestOptions()
            .placeholder(placeholderImage)   //占位图
            .error(placeholderImage)         //错误图
        Glide.with(context).load(drawableId).apply(options).into(imageView)
    }

    /**
     * 加载本地路径文件
     * @param drawableId 资源id
     */
    fun loadImageDrawableIdWithBorder(
        context: Context?,
        @DrawableRes drawableId: Int,
        imageView: ImageView?,
        borderSize: Float = 1f,
        @ColorRes borderColor: Int = android.R.color.white,
        @DrawableRes placeholder: Int = placeholderImage,
    ) {
        if (context == null || drawableId == 0 || imageView == null) return

        val options = RequestOptions.bitmapTransform(
            MultiTransformation(
                CenterCrop(),
                CropCircleWithBorderTransformation(SizeUtils.dp2px(borderSize), ColorUtils.getColor(borderColor))
            )
        )
            .placeholder(placeholder)   //占位图
            .error(placeholder)               //错误图
        Glide.with(context).load(drawableId).apply(options).into(imageView)
    }

    /**
     * 指定图片大小;使用override()方法指定了一个图片的尺寸。
     * Glide现在只会将图片加载成width*height像素的尺寸，而不会管你的ImageView的大小是多少了。
     * 如果你想加载一张图片的原始尺寸的话，可以使用Target.SIZE_ORIGINAL关键字----override(Target.SIZE_ORIGINAL)
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param width     图片宽度
     * @param height    图片高度
     */
    fun loadImageSize(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        width: Int,
        height: Int,
        @DrawableRes placeholder: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions()
            .placeholder(placeholder) //占位图
            .error(placeholder) //错误图
            .override(width, height)
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 禁用内存缓存功能
     * diskCacheStrategy()方法基本上就是Glide硬盘缓存功能的一切，它可以接收五种参数：
     *
     *
     * DiskCacheStrategy.NONE： 表示不缓存任何内容。
     * DiskCacheStrategy.DATA： 表示只缓存原始图片。
     * DiskCacheStrategy.RESOURCE： 表示只缓存转换过后的图片。
     * DiskCacheStrategy.ALL ： 表示既缓存原始图片，也缓存转换过后的图片。
     * DiskCacheStrategy.AUTOMATIC： 表示让Glide根据图片资源智能地选择使用哪一种缓存策略（默认选项）。
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */
    fun loadImageSizeKipMemoryCache(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        @DrawableRes placeholder: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions()
            .placeholder(placeholder)         //占位图
            .error(placeholder)               //错误图
            .skipMemoryCache(true)       //禁用掉Glide的内存缓存功能
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 预先加载图片
     * 在使用图片之前，预先把图片加载到缓存，调用了预加载之后，我们以后想再去加载这张图片就会非常快了，
     * 因为Glide会直接从缓存当中去读取图片并显示出来
     *
     * @param context 上下文
     * @param url     链接
     */
    fun preloadImage(context: Context?, url: String?,priority: Priority = Priority.LOW) {
        if (context == null || url.isNullOrEmpty()) return
        val options = RequestOptions().priority(priority)
        Glide.with(context).load(url).apply(options).preload()
    }

    /**
     * 加载圆形图片
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */
    fun loadCircleImage(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        @DrawableRes placeholder: Int = R.drawable.ic_default_rec,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions()
            .dontAnimate()
            .centerCrop()
            .circleCrop()               //设置圆形
            .placeholder(placeholder)   //占位图
            .error(placeholder)         //错误图
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 加载圆形带边框图片
     *
     * @param context     上下文
     * @param url         链接
     * @param imageView   ImageView
     * @param borderSize  边框宽度 px
     * @param borderColor 边框颜色
     */
    fun loadCircleWithBorderImage(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        borderSize: Float = 1f,
        @ColorRes borderColor: Int = android.R.color.white,
        @DrawableRes placeholder: Int = R.drawable.ic_default_rec,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions
            .bitmapTransform(
                MultiTransformation(
                    CenterCrop(),
                    CropCircleWithBorderTransformation(SizeUtils.dp2px(borderSize), ColorUtils.getColor(borderColor))
                )
            )
            .placeholder(placeholder)        //占位图
            .error(placeholder)              //错误图
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 加载圆角图片
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param radius    圆角 px
     */
    fun loadRoundImage(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        radius: Float,
        @DrawableRes placeholder: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions.bitmapTransform(
            MultiTransformation(
                CenterCrop(),
                RoundedCornersTransformation(SizeUtils.dp2px(radius), 0, RoundedCornersTransformation.CornerType.ALL)
            )
        )
            .dontAnimate()
            .placeholder(placeholder)   //占位图
            .error(placeholder)         //错误图
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 加载圆角图片-指定任意部分圆角（图片上、下、左、右四个角度任意定义）
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param radius    圆角 px
     * @param type      圆角位置
     */
    fun loadRoundImage(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        radius: Float,
        type: RoundedCornersTransformation.CornerType?,
        @DrawableRes placeholder: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions.bitmapTransform(
            MultiTransformation(
                CenterCrop(),
                RoundedCornersTransformation(SizeUtils.dp2px(radius), 0, type)
            )
        )
            .dontAnimate()
            .placeholder(placeholder)   //占位图
            .error(placeholder)         //错误图
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 加载圆角图片
     *
     * @param context   上下文
     * @param path       文件路径
     * @param imageView ImageView
     * @param radius    圆角 px
     */
    fun loadRoundImageByFilePath(
        context: Context?,
        path: String?,
        imageView: ImageView?,
        radius: Float,
        @DrawableRes placeholder: Int = placeholderImage,
    ) {
        if (context == null || !FileUtils.isFileExists(path) || imageView == null) return

        val options = RequestOptions.bitmapTransform(
            MultiTransformation(
                CenterCrop(),
                RoundedCornersTransformation(SizeUtils.dp2px(radius), 0, RoundedCornersTransformation.CornerType.ALL)
            )
        )
            .placeholder(placeholder) //占位图
            .error(placeholder)    //错误图
        Glide.with(context).load(path).apply(options).into(imageView)
    }

    /**
     * 加载模糊图片（自定义透明度）
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param blur      模糊度，一般1-100够了，越大越模糊
     */
    fun loadRadiusBlurImage(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        blur: Int,
        radius: Float,
        @DrawableRes placeholder: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions.bitmapTransform(
            MultiTransformation(
                CenterCrop(),
                BlurTransformation(blur),
                RoundedCornersTransformation(SizeUtils.dp2px(radius), 0, RoundedCornersTransformation.CornerType.ALL)
            )
        )
            .placeholder(placeholder) //占位图
            .error(placeholder) //错误图
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 加载模糊图片（自定义透明度）
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     * @param blur      模糊度，一般1-100够了，越大越模糊
     * @param sampling  取样
     */
    fun loadBlurImage(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        blur: Int,
        sampling: Int,
        @DrawableRes placeholder: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions.bitmapTransform(
            MultiTransformation(
                CenterCrop(),
                BlurTransformation(blur, sampling)
            )
        )
            .placeholder(placeholder) //占位图
            .error(placeholder) //错误图
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 加载灰度(黑白)图片（自定义透明度）
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */
    fun loadBlackImage(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        @DrawableRes placeholder: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions.bitmapTransform(
            MultiTransformation(
                CenterCrop(),
                GrayscaleTransformation()
            )
        )
            .placeholder(placeholder) //占位图
            .error(placeholder) //错误图
            .priority(priority)
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * @param context         上下文
     * @param url             下载链接
     * @param result          下载结果
     */
    fun downloadFile(context: Context?, url: String?, result: (file: File?) -> Unit) {
        if (context == null || url.isNullOrEmpty()) {
            result.invoke(null)
            return
        }

        Glide.with(context)
            .downloadOnly()
            .load(url)
            .priority(Priority.IMMEDIATE)
            .addListener(object : RequestListener<File?> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<File?>, isFirstResource: Boolean): Boolean {
                    e?.printStackTrace()
                    workUI { result.invoke(null) }
                    return false
                }

                override fun onResourceReady(resource: File, model: Any, target: Target<File?>?, dataSource: DataSource, isFirstResource: Boolean): Boolean {
                    workUI { result.invoke(resource) }
                    return false
                }
            })
            .preload()
    }

    /**
     * 下载Bitmap
     */
    fun downloadBitmap(context: Context?, url: String?, width: Int = 100, height: Int = 100, result: (bmp: Bitmap?) -> Unit) {
        if (context == null || url.isNullOrEmpty()) {
            result.invoke(null)
            return
        }

        Glide.with(context)
            .asBitmap()
            .skipMemoryCache(false)
            .load(url)
            .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
            .priority(Priority.IMMEDIATE)
            .listener(object : RequestListener<Bitmap> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>, isFirstResource: Boolean): Boolean {
                    workUI { result.invoke(null) }
                    return false
                }

                override fun onResourceReady(resource: Bitmap, model: Any, target: Target<Bitmap>?, dataSource: DataSource, isFirstResource: Boolean): Boolean {
                    workUI { result.invoke(resource) }
                    return true
                }
            })
            .submit(width, height)
    }

    /**
     * 下载Bitmap
     */
    fun downloadCircleBitmap(context: Context?, url: String?, width: Int = 100, height: Int = 100, result: (bmp: Bitmap?) -> Unit) {
        if (context == null || url.isNullOrEmpty()) {
            result.invoke(null)
            return
        }

        Glide.with(context)
            .asBitmap()
            .skipMemoryCache(false)
            .transform(CircleCrop())
            .load(url)
            .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
            .priority(Priority.IMMEDIATE)
            .listener(object : RequestListener<Bitmap> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>, isFirstResource: Boolean): Boolean {
                    workUI { result.invoke(null) }
                    return false
                }

                override fun onResourceReady(resource: Bitmap, model: Any, target: Target<Bitmap>?, dataSource: DataSource, isFirstResource: Boolean): Boolean {
                    workUI { result.invoke(resource) }
                    return true
                }
            })
            .submit(width, height)
    }

    /**
     * 清除缓存
     */
    fun clear(context: Context) {
        workIO { Glide.get(context).clearDiskCache() }
    }

    /**
     * 加载图片(默认)
     *
     * @param context   上下文
     * @param url       链接 或 本地文件路径 或 asset路径
     * @param imageView ImageView
     */
    fun loadImageByVip(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        level: Int?,
        @DrawableRes placeholder: Int = placeholderImage,
        priority: Priority = Priority.NORMAL
    ) {
        if (context == null || imageView == null) return

        val options = RequestOptions()
            .placeholder(placeholder)   //占位图
            .error(placeholder)         //错误图
            .priority(priority)

        if (level == null || level < 5) { //gifUrl显示第一帧
            options.dontAnimate()
        }
        Glide.with(context).load(url).apply(options).into(imageView)
    }

    /**
     * 加载业务头像
     *
     * @param context   上下文
     * @param url       链接
     * @param imageView ImageView
     */
    fun loadAvatarByVip(
        context: Context?,
        url: String?,
        imageView: ImageView?,
        level: Int?,
        isNeedBorder: Boolean = false,
        @ColorRes borderColor: Int = android.R.color.white,
        borderSize: Float = 1f,
        placeholderImage: Int = R.drawable.ic_default_rec,
        priority: Priority = Priority.HIGH
    ) {
        if (context == null || imageView == null) return

        val options = if (isNeedBorder) {
            RequestOptions.bitmapTransform(
                MultiTransformation(
                    CenterCrop(),
                    CropCircleWithBorderTransformation(SizeUtils.dp2px(borderSize), ColorUtils.getColor(borderColor))
                )
            )
        } else {
            RequestOptions()
                .centerCrop()
                .circleCrop() //设置圆形
        }

        options.placeholder(placeholderImage) //占位图
            .error(placeholderImage) //错误图
            .priority(priority)

        if (level == null || level < 5) { //gifUrl显示第一帧
            options.dontAnimate()
        }
        Glide.with(context).load(url).apply(options).into(imageView)
    }

}